/**
 * 该文件，用于封装 axios
 */

import axios from "axios"
import store from "@/store"
import store2 from "store2"
import { ElMessage } from "element-plus"

// 创建一个 axios 的实例，并配置一些默认的参数
const instance = axios.create({
  // 设置一些默认配置项

  /**
   * 基准地址
   *    request.get('/api')       => http://127.0.0.1:5173/api
   *    request.get('/abcd')      => http://127.0.0.1:5173/abcd
   *    request.get('https://hello.com/api')    => https://hello.com/api
   *
   * : 后续处理本地开发与生产上线的环境变量
   */
  // baseURL:
  //   import.meta.env.MODE === "development"
  //     ? "/api"
  //     : import.meta.env.MODE === "STG"
  //     ? "https://stg.com/api"
  //     : import.meta.env.MODE === "UAT"
  //     ? "https://uat.com/api"
  //     : "https://www.baidu.com/api",
  baseURL: import.meta.env.VITE_API_BASEURL,
  // baseURL: "/api",


  /**
   * 超时时间，单位是 毫秒
   */
  timeout: 3 * 1000,

  /**
   * 自定义请求头
   */
  headers: {
    hello: "world",
  },
});

/**
 * 请求拦截器
 */
instance.interceptors.request.use(
  /**
   * 成功的回调
   *    1. config 是请求的配置对象
   *    2. 必须返回该 config
   *    应用场景：
   *      1. 统一携带 token 到请求头中。
   */
  (config) => {
    const token = store2.get("token")
    if (token) {
      config.headers.Authorization = token
    }
    return config
  },
  /**
   * 失败的回调
   *    1. error 是请求失败的原因
   *    2. 必须返回 Promise.reject(error)
   *    触发时机：
   *        
   */
  (error) => {
    return Promise.reject(error)
  }
)

/**
 * 响应拦截器
 */
instance.interceptors.response.use(
  /**
   * 成功的回调
   *    1. response 是 axios 的包装对象
   *    2. 必须要返回数据，返回的数据是 .then 的回调函数的参数'
   *    触发时机：
   *      1. 接口请求成功，也就是 HTTP 状态码要为 2xx 或 304
   *      2. 会在业务代码的 .then 之前触发
   */
  (response) => {
    // 1. 解构 data
    const { data } = response
    // 2. 判断业务状态码
    if (data.code === 1000) {
      return data.data
    } else {
      // 业务失败，抛出错误，消息提示
      ElMessage.error(data.message)
      return Promise.reject(response)
    }
  },
  /**
   * 失败的回调
   *    1. error 是失败的原因
   *    2. 必须要返回 Promise.reject(error)
   *    触发时机：
   *      1. HTTP 状态码 为 非 2xx 或 304
   */
  (error) => {
    //根据HTTP状态码判断错误类型
    let response = error.response
    if (!response) {
      response = {
        status: 500,
        data: {
          message: "网络异常，请稍后再试!"
        }
      }
    }
    // 1.获取HTTP状态码
    const { status, data: { message } } = response
    // 3.根据HTTP状态码，做不同的处理
    switch (status) {
      case 401:
        ElMessage.error(message || "登录失效或无权限访问~");
        // 只清理本地，不再请求 logout 接口
        store.dispatch("user/logout", false);
        break;
      case 502:
        ElMessage.error("网关错误")
        break
      case 503:
        ElMessage.error("服务器异常，请稍后再试")
        break
      default:
        //Other
        ElMessage.error(message)
    }
    return Promise.reject(error) // 关键：必须返回 rejection
  })

// end 将 实例给暴露出去
export default instance
